// DLLSocket.cpp : Defines the entry point for the console application.


#include "stdafx.h"
#include <iostream>
#include <Windows.h>		//includes ::GetProcAddress and ::GetLastError
#include "DLLInterface.h"

const wchar_t	  *ConvertStrTowStr(wchar_t *dest, size_t destBuffwCharsLen, const char *source, size_t sourceStrLenMax);

int _tmain(int argc, _TCHAR* argv[])
{	
	std::cout << "****Launching program PlayDLL2 v1.0.0****" << std::endl;

	wchar_t	wcTempBuffer[500+1];					//conversion buffer, used by the string conversion
	const wchar_t *pwStrPathFileName = '\0';		//DLL file

	if ((pwStrPathFileName = ConvertStrTowStr(wcTempBuffer, 500, "PlayDLL2.dll", (size_t)500/sizeof(wchar_t))) == '\0')
		std::cout << "Error: unable to convert pathfilenameDll" << std::endl;
	else
	{	using namespace std;
		//load DLL
		HINSTANCE hInstance = NULL;
		hInstance = ::LoadLibrary(wcTempBuffer);

		//Error checking
		if((hInstance = ::LoadLibrary(wcTempBuffer)) == NULL)
		{
			std::cout << "Error: unable to load lib" << std::endl;
		}
		else
		{
			cout << "> DLL loaded" << endl;

			int (*pfn)(void) = 0;

			//Call function to return 5
			if (pfn == '\0')
			{
				cout << "pfn initialised" << endl;
			}
			*(FARPROC *)&pfn = ::GetProcAddress(hInstance, "CallReturn5");

			if (pfn == '\0')
			{
				cout << "pfn not initialised, error:" << endl;
				cout <<  ::GetLastError() << endl;
			}
			else
			{
				cout << "pfn assigned to CallReturn. CallReturn = "
					 << pfn() << endl;
			}

			//Call function to return class

			IFrame* lib = '\0';			// pointer
			IFrame* (*pfn2)(void) = 0;	// pointer
			*(FARPROC *)&pfn2 = ::GetProcAddress(hInstance, "Create");

			
			if (pfn2 == '\0')
			{
				cout << "pfn2 not initialised" << endl;
				cout <<  ::GetLastError() << endl;
			}
			else
			{	
				lib = pfn2();
				cout << "pfn2 is " << lib->getvalue() << endl;
				lib->Delete();
			}

		}
	}



	std::cout << "Program executed successfully" << std::endl;
	return 0;
}

const wchar_t	  *ConvertStrTowStr(wchar_t *dest, size_t destBuffwCharsLen, const char *source, size_t sourceStrLenMax)
{
	const wchar_t *rc = '\0';

	if ((dest == '\0') || (source == '\0') || (destBuffwCharsLen < 1) || (sourceStrLenMax < 1))
		std::cout << "Error: ConvertStrTowStr() has invalid params" << std::endl;
	else
	{
		size_t   convertCnt = 0;
		size_t   sourceCnt = strnlen(source, sourceStrLenMax+1 ) + 1;	//if source is not terminated or is longer than sourceStrLenMax, then strnlen returns sourcewStrLenMax+1 so convertCnt != sourceCnt

		if ( (mbstowcs_s(&convertCnt, dest, destBuffwCharsLen, source, sourceStrLenMax) != 0 ) || (convertCnt != sourceCnt))
			std::cout << "Error: mbstowcs_s failed, " << std::endl;
		else
			rc = dest;
	}
	return rc;
}
